home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-01-06 | 9.3 KB | 347 lines | [TEXT/KAHL] |
-
- /* Prototypes */
- PicHandle CreatePICT2( PixMap *srcBits, Rect *srcRect, Rect *dstRect, short mode );
- void PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect, Rect *dstRect, short mode );
- long PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr );
- long PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr );
-
- PicHandle
- CreatePICT2(PixMap *srcBits, Rect *srcRect, Rect *dstRect,
- short mode)
- {
- PicHandle myPic;
- short myRowBytes;
- short *picPtr;
- short iii;
- long handleSize;
-
- #define CLIPSIZE 12
- #define PIXMAPRECSIZE 50
- #define HEADERSIZE 40
- #define MAXCOLORTABLESIZE 256*8+8
- #define OPCODEMISCSIZE 2+8+8+2 /* opcode+srcRect+dstRect+mode */
- #define ENDOFPICTSIZE 2
- #define PICSIZE PIXMAPRECSIZE + HEADERSIZE + MAXCOLORTABLESIZE +\
- ENDOFPICTSIZE + OPCODEMISCSIZE + CLIPSIZE
-
- myRowBytes = srcBits->rowBytes & 0x3fff;
- /* Allocate worst-case memory scenario using PackBits packing. */
- myPic = (PicHandle) NewHandle( PICSIZE +
- (long)((myRowBytes/127)+2+myRowBytes)*(long)(srcBits->bounds.bottom
- - srcBits->bounds.top));
- if(!myPic)
- return(0);
-
- /* Skip picSize and put out picFrame (10 bytes). */
- picPtr = (short *) (((long)*myPic) + 2);
- *picPtr++ = dstRect->top;
- *picPtr++ = dstRect->left;
- *picPtr++ = dstRect->bottom;
- *picPtr++ = dstRect->right;
-
- /* Put out header (30 bytes). This could be done from a resource or
- taken from an existing picture. */
- *picPtr++ = 0x11; /* Version opcode. */
- *picPtr++ = 0x2ff; /* Version number. */
- *picPtr++ = 0xC00; /* Header opcode. */
- *picPtr++ = 0xFFFF; /* Put out PICT header version. */
- *picPtr++ = 0xFFFF;
- /* The rest of the header is ignored--0 it out. */
- for(iii = 10; iii > 0; iii--)
- *picPtr++ = 0; /* Write out 24 bytes of 0. */
-
- /* Put out current port's clip region. */
- *picPtr++ = 0x01;
- *picPtr++ = 0x0A; /* Clip region only has bounds rectangle. */
- *picPtr++ = (**thePort->clipRgn).rgnBBox.top;
- *picPtr++ = (**thePort->clipRgn).rgnBBox.left;
- *picPtr++ = (**thePort->clipRgn).rgnBBox.bottom;
- *picPtr++ = (**thePort->clipRgn).rgnBBox.right;
-
- HLock(myPic);
- if(srcBits->pixelType == RGBDirect)
- { /* Must be 32-bits/pixel */
- /* Put out opCode $9A, DirectBitsRect. */
- *picPtr++ = 0x9A;
- *picPtr++ = 0; /* BaseAddr for direct pixMaps is 0x000000FF. */
- *picPtr++ = 0xFF;
- PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
- dstRect, mode);
- if(PutOutPackedDirectPixData(srcBits, &picPtr)) /* Nonzero
- indicates an error. */
- goto errorExit;
- }
- else
- {
- /* Put out opCode $98, PackBitsRect. */
- *picPtr++ = 0x98;
- PutOutPixMapSrcRectDstRectAndMode(srcBits, &picPtr, srcRect,
- dstRect, mode);
- if(PutOutPackedIndexedPixData(srcBits, &picPtr)) /* Nonzero
- indicates an error. */
- goto errorExit;
-
- }
- HUnlock(myPic);
-
- /* All done! Put out end-of-picture opcode, $00FF. */
- *picPtr++ = 0x00FF;
-
- /* Size handle down to the amount actually used. */
- handleSize = (long) picPtr - (long) *myPic;
- SetHandleSize( myPic, handleSize );
- /* Write out picture size. */
- *((short *)*myPic) = (short) handleSize;
- return(myPic);
-
- errorExit:
- DisposHandle(myPic);
- return(0);
- }
-
-
- void
- PutOutPixMapSrcRectDstRectAndMode( PixMap *srcBits, short** inPicPtr, Rect *srcRect,
- Rect *dstRect, short mode )
- {
- short iii;
- short * picPtr = *inPicPtr;
- short myRowBytes = srcBits->rowBytes & 0x3fff;
-
- /* put out pixMap */
- *picPtr++ = srcBits->rowBytes | 0x8000; /*always make PixMaps */
- *picPtr++ = srcBits->bounds.top; /* Bounds */
- *picPtr++ = srcBits->bounds.left;
- *picPtr++ = srcBits->bounds.bottom;
- *picPtr++ = srcBits->bounds.right;
- *picPtr++ = 0; /* version number */
- /*
- ** Put out packing format:
- ** 0 is default indexed packing.
- ** 1 is no packing (rowBytes < 8 )
- ** 4 is default direct packing - run length encoded scan lines by component, red first.
- */
- if( myRowBytes < 8 && myRowBytes > 0 )
- *picPtr++ = 1; /* packing format: unpacked */
- else
- {
- if( srcBits->pixelType == RGBDirect )
- *picPtr++ = 4;
- else
- *picPtr++ = 0; /* packing format: standard */
- }
-
- *picPtr++ = 0; /* packed size */
- *picPtr++ = 0;
- *picPtr++ = 0x48; /* horizontal resolution: $0048 0000 */
- *picPtr++ = 0;
- *picPtr++ = 0x48; /* vertical resolution: $0048 0000 */
- *picPtr++ = 0;
-
- /* these fields are different for BitMap/PixMap */
- if( srcBits->rowBytes < 0 )
- {/* do PixMap */
- *picPtr++ = srcBits->pixelType;
- *picPtr++ = srcBits->pixelSize; /* pixel size */
- *picPtr++ = srcBits->cmpCount; /* number of components */
- *picPtr++ = srcBits->cmpSize; /* size of each component */
- }
- else
- {/* do BitMap */
- *picPtr++ = 0;
- *picPtr++ = 1; /* pixel size */
- *picPtr++ = 1; /* number of components */
- *picPtr++ = 1; /* size of each component */
- }
-
- *picPtr++ = 0; /* offset to next plane */
- *picPtr++ = 0;
-
- if( srcBits->pixelType == RGBDirect )
- {
- *picPtr++ = 0; /* color table is nil for Direct pixmaps*/
- *picPtr++ = 0;
- }
- else
- {
- *picPtr++ = (unsigned short) srcBits->pmTable>>16; /* color table */
- *picPtr++ = (unsigned short) srcBits->pmTable;
- }
-
- *picPtr++ = 0; /* reserved */
- *picPtr++ = 0;
-
- /* put out colortable if indexed pixmap*/
- if( (srcBits->rowBytes < 0) && (srcBits->pmTable) && (srcBits->pixelType != RGBDirect) )
- {
- short* ctPtr = (short *) *(srcBits->pmTable); /* Get ptr to color table */
- *picPtr++ = *ctPtr++; /* copy ctSeed */
- *picPtr++ = *ctPtr++;
- *picPtr++ = *ctPtr++; /* copy ctFlags */
- iii = *ctPtr;
- *picPtr++ = *ctPtr++; /* copy ctSize */
- for( ; iii >= 0; iii-- )
- {/* put out all entries */
- *picPtr++ = *ctPtr++; /* pixel value */
- *picPtr++ = *ctPtr++; /* red */
- *picPtr++ = *ctPtr++; /* green */
- *picPtr++ = *ctPtr++; /* blue */
- }
- }
- else
- if( srcBits->pixelType != RGBDirect )
- {
- for( iii = 8; iii > 0; iii-- )
- *picPtr++ = 0; /* put out an empty color table: 8 words of 0 */
- }
-
- /* put out srcrect, dstrect, and mode */
- *picPtr++ = srcRect->top;
- *picPtr++ = srcRect->left;
- *picPtr++ = srcRect->bottom;
- *picPtr++ = srcRect->right;
-
- *picPtr++ = dstRect->top;
- *picPtr++ = dstRect->left;
- *picPtr++ = dstRect->bottom;
- *picPtr++ = dstRect->right;
-
- *picPtr++ = mode;
- *inPicPtr = picPtr;
- }
-
- long
- PutOutPackedIndexedPixData( PixMap *srcBits, short **picPtr )
- {
- Ptr srcPtr = srcBits->baseAddr;
- Ptr dstPtr;
- Ptr packBuf;
- Ptr tempPicPtr = (char*) *picPtr;
- short packedSize;
- short iii, jjj;
- unsigned short myRowBytes;
-
- myRowBytes = srcBits->rowBytes & 0x3fff;
-
- /* put out PixData */
- if( myRowBytes < 8 )
- { /* no packing */
- short * pixMapPtr = (short *) srcBits->baseAddr;
- for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
- *tempPicPtr++ = *pixMapPtr++;
- return( 0 );
- }
-
- packBuf = (Ptr)NewPtr( myRowBytes * 2 );
- if( !packBuf )
- return( -1 );
-
- /* Must use only byte accesses to avoid address errors on 68K class machines */
-
- for( iii = srcBits->bounds.bottom - srcBits->bounds.top; iii > 0; iii-- )
- {
- dstPtr = packBuf;
- PackBits( &srcPtr, &dstPtr, myRowBytes );
- packedSize = (long)dstPtr - (long)packBuf;
- if( myRowBytes <= 250 )
- { /* put a byte to the picture */
- *tempPicPtr++ = (unsigned char)packedSize;
- }
- else
- { /* put a word to the picture */
- *tempPicPtr++ = (unsigned char)(packedSize>>8);
- *tempPicPtr++ = (unsigned char)packedSize;
- }
- /* put the packed data out */
- dstPtr = packBuf;
- for( jjj = packedSize; jjj > 0; jjj-- )
- {
- *tempPicPtr++ = *dstPtr++;
- }
- }
- DisposPtr( packBuf );
- if( (long)tempPicPtr & (long)0x0001 ) /* do long alignment */
- tempPicPtr++;
- *picPtr = (short *) tempPicPtr;
- return( 0 );
- }
-
-
- long
- PutOutPackedDirectPixData( PixMap *srcBits, short **picPtr )
- {
- Ptr srcPtr;
- Ptr dstPtr;
- Ptr packBuf;
- Ptr srcBuf;
- Ptr srcBufPtr;
- Ptr tempPicPtr = (char*) *picPtr;
- short packedSize;
- short iii, jjj, kkk;
- unsigned short myRowBytes = srcBits->rowBytes & 0x3fff;
- unsigned short componentRowBytes = myRowBytes>>2;
-
- /* put out PixData */
- if( myRowBytes < 8 )
- { /* no packing */
- short * pixMapPtr = (short *) srcBits->baseAddr;
- for( iii = (myRowBytes*(srcBits->bounds.bottom - srcBits->bounds.top))/2; iii > 0; iii-- )
- *tempPicPtr++ = *pixMapPtr++;
- return( 0 );
- }
-
- packBuf = (Ptr)NewPtr( myRowBytes * 2 );
- if( !packBuf )
- return( -1 );
-
- /* allocate a buffer for separating the components */
-
- srcBuf = (Ptr)NewPtr( componentRowBytes*3 );
- if( !srcBuf )
- return( -1 );
-
- /* Must use only byte accesses to avoid address errors on 68K class machines */
-
- for( iii = 0; iii < srcBits->bounds.bottom - srcBits->bounds.top; iii++ )
- {
- srcBufPtr = srcBuf;
- for( jjj = 1; jjj <= 3; jjj++ ) /* Do red, green, and blue */
- {
- srcPtr = srcBits->baseAddr + (unsigned long)myRowBytes * iii;
- srcPtr += jjj; /*point to this component */
- for( kkk = 0; kkk < componentRowBytes; kkk++ )
- {
- *srcBufPtr++ = *srcPtr;
- srcPtr += 4;
- }
- }
-
- dstPtr = packBuf;
- srcBufPtr = srcBuf;
- PackBits( &srcBufPtr, &dstPtr, componentRowBytes*3 );
-
- packedSize = (long)dstPtr - (long)packBuf;
- if( myRowBytes <= 250 )
- { /* put a byte to the picture */
- *tempPicPtr++ = (unsigned char)packedSize;
- }
- else
- { /* put a word to the picture */
- *tempPicPtr++ = (unsigned char)(packedSize>>8);
- *tempPicPtr++ = (unsigned char)packedSize;
- }
- /* put the packed data out */
- dstPtr = packBuf;
- for( kkk = packedSize; kkk > 0; kkk-- )
- {
- *tempPicPtr++ = *dstPtr++;
- }
- }
- DisposPtr( packBuf );
- DisposPtr( srcBuf );
- if( (long)tempPicPtr & (long)0x0001 ) /* do long alignment */
- tempPicPtr++;
- *picPtr = (short *) tempPicPtr;
- return( 0 );
- }
-